<template>
  <el-select
    v-model="selectedValue"
    :placeholder="placeholder"
    :clearable="clearable"
    :filterable="filterable"
    :multiple="multiple"
    :style="{ width: width }"
    @change="handleChange"
    @clear="handleClear"
  >
    <el-option
      v-for="item in dictOptions"
      :key="item.value"
      :label="item.label"
      :value="item.value"
    />
  </el-select>
</template>

<script setup>
import { ref, watch, onMounted } from "vue";
import { useDictStore } from "@/stores/dict";

const props = defineProps({
  // 字典类型
  dictType: {
    type: String,
    required: true,
  },
  // 占位符文本
  placeholder: {
    type: String,
    default: "请选择",
  },
  // 默认值
  modelValue: {
    type: [String, Number, Array],
    default: "",
  },
  // 是否可清空
  clearable: {
    type: Boolean,
    default: true,
  },
  // 是否可搜索
  filterable: {
    type: Boolean,
    default: true,
  },
  // 是否多选
  multiple: {
    type: Boolean,
    default: false,
  },
  // 宽度
  width: {
    type: String,
    default: "100%",
  },
  // 是否包含全部选项
  includeAll: {
    type: Boolean,
    default: false,
  },
  // 全部选项的文本
  allText: {
    type: String,
    default: "全部",
  },
});

const emit = defineEmits(["update:modelValue", "change"]);

const dictStore = useDictStore();
// 选中的值
const selectedValue = ref(props.modelValue);
// 字典选项
const dictOptions = ref([]);
// 加载状态
const loading = ref(false);

// 监听外部值变化
watch(
  () => props.modelValue,
  (newVal) => {
    selectedValue.value = newVal;
  }
);

// 监听内部值变化
watch(selectedValue, (newVal) => {
  emit("update:modelValue", newVal);
  emit("change", newVal);
});

// 加载字典数据
const loadDictData = async () => {
  if (!props.dictType) return;

  loading.value = true;
  try {
    const response = await dictStore.fetchDictDataByType({ code: props.dictType });

    let options = [];

    // 添加全部选项
    if (props.includeAll) {
      options.push({
        value: "",
        label: props.allText,
      });
    }

    // 添加字典数据
    if (response) {
      options = options.concat(
        response.map((item) => ({
          value: item.value,
          label: item.label,
        }))
      );
    }

    dictOptions.value = options;
  } catch (error) {
    // 加载字典数据失败处理
    dictOptions.value = [];
  } finally {
    loading.value = false;
  }
};

// 处理选择变化
const handleChange = (value) => {
  emit("change", value);
};

// 处理清空
const handleClear = () => {
  emit("change", "");
};

// 重新加载数据
const reload = () => {
  dictStore.reloadDictData({ code: props.dictType });
};

// 暴露方法给父组件
const getOptions = () => dictOptions.value;

defineExpose({
  reload,
  getOptions,
});

// 组件挂载时加载数据
onMounted(() => {
  loadDictData();
});
</script>

<style scoped>
/* 可以添加自定义样式 */
</style>